package com.cetc;

import com.cetc.domain.Person;
import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @Classname ReflectionTest
 * @Description 反射测试
 * @Date 2022/11/26 17:24
 * @Created by louzhuangxi
 */
public class ReflectionTest {
    @Test
    public void test01() {
        Person person = new Person("Tom", 12);
        person.age = 11;
        System.out.println(person.toString());
        person.show();
        //在Person类中不能够调用私有内部结构
    }

    @Test
    public void test02() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException, NoSuchFieldException {
        //1.通过反射创建对象
        Class clazz = Person.class;
        Constructor cons = clazz.getConstructor(String.class, int.class);
        Person person = (Person)cons.newInstance("Tom", 12);
        System.out.println(person);
        //2.通过反射调用指定的属性/方法
        Field age = clazz.getDeclaredField("age");
        age.set(person,10);
        System.out.println(person);
        //3.通过反射调用方法
        Method method = clazz.getDeclaredMethod("show");
        method.invoke(person);

        //4.通过反射调用Person类的私有结构
        Constructor cons2 = clazz.getDeclaredConstructor(String.class);
        cons2.setAccessible(true);
        Person person1 = (Person) cons2.newInstance("Jerry");
        System.out.println(person1);

        //5.调用私有属性
        Field name = clazz.getDeclaredField("name");
        name.setAccessible(true);
        name.set(person1,"ZhangSan");
        System.out.println(person1);
        //6.调用私有方法
        Method showNation = clazz.getDeclaredMethod("showNation", String.class);
        showNation.setAccessible(true);
        showNation.invoke(person1,"中国");
    }
}
